File format for Lifeguard 1.01 Effects Modules (&400, GuardMod)
===============================================================


===========================================================================
Offset  Length   Contents
(dec)   (dec)
---------------------------------------------------------------------------
0       8        GUARDMOD (&52415547, &444F4D44)
8       4        Version number of Lifeguard that this effect module was
                 written for, times by 100 (eg. 1.04*100=104)
12      4        Flags (see below)
16      4        Required mode for effect (see below)
20      28       Short name of the effect (padded with zeros)
48      34       First line of long name of the effect (padded with zeros)
82      34       Second line of long name of the effect (padded with zeros)
116     34       Third line of long name of the effect (padded with zeros)
150     34       Author's name (padded with zeros)
184     4        B initialise_code
188     4        B vsync_code
192     4        B finalise_code
196     4        Reserved; MUST BE 0
200     ...      ...
===========================================================================


NB: Any of the entry points can be left out (by replacing them with
--  MOVS PC,R14) if you wish. If the vsync_code entry is left out, however,
    all that will happen is that the screen will turn black (because
    Lifeguard will change mode to the one you have asked for, call the
    intialise code and then not call your code again until it gets to the
    finalise entry). The 'Black' example effect has no entry points at all.

    R2-R5 can be used for storing things in. These will start as all 0 on
    the call to Initialise, then they will remain constant from call to call
    until the Finalise entry is called, after which the values are
    forgotten.

    Remember that your code must be fully relocatable, as it will move about
    when Lifeguard is first loaded, and when the user removes effects above
    your one in the effects file.


Initialise code
---------------

On entry:
   R0    = Version number of Lifeguard*100
   R1    = Current screen mode
   R2-R5 = 0
   R13   = Stack
On exit:
   R0    = 0 if effect refuses to initialise
   R2-R5 = Work registers
   All registers above R5 (R6-R13) must be preserved

   This code is called once, when the screen is due to be 'blanked'. It
should claim any workspace needed and check that everything is OK for the
effect to be displayed. If the effect cannot start up for any reason, R0
should be 0 on exit. Any other value than 0 will be assumed to mean that the
effect has initialised OK. The code MUST preserve ALL registers other than
R0-R5.
   Note that, although Lifeguard will try to change to the mode that you
request, it may not be able to, eg. because of insufficient memory.
Therefore, if your code is not guaranteed to work in ALL modes, it should
check the mode given in R1, and refuse to initialise if it doesn't like it.


VSync code
----------

On entry:
   R0    = 0
   R2-R5 = Work registers
   R13   = Stack
On exit:
   R0    = -1 means effect has finished
   R2-R5 = New work registers
   All registers above R5 (R6-R13) must be preserved

   This code is called on every available VSync while the effect is being
displayed. This code should display the effect, move it, whatever. The code
MUST preserve ALL registers.
   If R0 = -1 on exit then Lifeguard will finalise your effect and choose
another one. This is used by 'Fade' to start another effect when the desktop
screen has faded out.
   Remember that you are still in the Desktop, so the code should be as
legal as possible. You can write directly to the screen, if you are sure
of the mode, and if you use legal calls to work out the screen address.


Finalise code
-------------

On entry:
   R2-R5 = Work registers
   R13   = Stack
On exit:
   All registers must be preserved

   This code is called when the effect is being closed down. It should
release any workspace, etc. It MUST preserve ALL registers.


Mode
----

    Normally, Lifeguard will attempt to change to the mode specified in the
effect's header, by using a Wimp_SetMode followed by a VDU 22,mode to reset
the palette, etc. If you specify the mode as -1 then the mode will not be
changed - this may be used in conjuction with bit 2 of the flags (see below).
Note that if you set the mode number to -1 then the screen will still be
wiped, unless you do set bit 2 of the flags.


Flags
-----

===========================================================================
Bit     Meaning if set    
---------------------------------------------------------------------------
0       Effect is enabled
1       Effect is selected
2       Leave the desktop screen in place
3-31    Reserved; MUST BE 0
===========================================================================

NB: Bits 0 and 1 must be set to 0 in the EffectMod file. These bits are set
--  by Lifeguard in the Effects file if the effect is enabled or selected.

    The only effect that should currently be set by effects writers is the
flag in bit 2. If this is set then Lifeguard will not wipe the screen before
starting the effect. This is so that you can write effects that use the old
screen, such as 'Fade'.


GuardRM
-------

    The Guard relocatable module is used to detect keypresses and mouse
clicks. It also provides an emergency or out-of-desktop screen blanker which
simply turns the screen black. It provides several SWIs. Apart from the two
below, you SHOULD NOT USE the SWIs, even if you think you know what they do
(it's pretty obvious from their names). You shouldn't have to use them
anyway - anything like changing the blanking delay should be done by the
user, not by another program.
    The are two SWIs you can use: Guard_ReadRandom and Guard_LargeRandom.
These are outlined below:


SWI Guard_ReadRandom

On entry:
    R0   = Maximum limit (1-8191)
On exit:
    R0   = Random number 0-limit
    Flags preserved

    This SWI returns a random number in the range 0-R0. The maximum limit is
8191. The number is brought within the correct range simply by repeatedly
subtracting the range until the number is within the range. If your range is
a power of two therefore, it is quicker to set a range of 8192 (or anything
larger) and then ANDing the number to get it in range.
    The random number routine is very simple, but should be good enough for
most purposes. It is seeded with the monotonic time when the Guard module is
first loaded.


SWI Guard_LargeRandom

On entry:
    R0   = Maximum limit (1-65535)
On exit:
    R0   = Random number 0-limit
    Flags preserved

    This is the same as Guard_ReadRandom, except that it can produce numbers
in the range 0-65535. The penalty for this is that it is slightly slower.
Therefore ReadRandom should be used where possible; only use LargeRandom
where you have to.
